using System;
using Gtk;
using System.Collections;
using System.IO;
using System.Configuration;
using Hildon;

public class MainWindow : Hildon.Window
{	
	private Table tableGame=null;
	private VBox board=null;

	// Declaration of the item menu that can change during the user interaction
	private MenuItem menuItemNew=null;
	private MenuItem menuItemStopGame = null;

	Toolbar tb = null;
	Label tbLabel=null;

	// Declaration of the players
	private int nPlayers;
	private Player[] players=new Player[4];
	private int runningPlayer=-1;

	// Declaration of the list of found image. 
	private String[] imageList;

	private ButtonMemory[] buttons=new ButtonMemory[96];
	
	private ButtonMemory firstButton=null;
	private ButtonMemory secondButton=null;
	
	private int buttonsToShow=36;
	private int sizeOfBoard=36;
	private bool isFullScreen=false;

//	public MainWindow () : base ("Monkey's Memory - V 0.1.0")
	public MainWindow ()
	{
		//this.Title="Monkey's Memory - V 0.1.5";

		ButtonMemory button=null;

		this.Icon=new Gdk.Pixbuf(null,"MonkeysMemory_small.png");;
		
		this.DeleteEvent += new DeleteEventHandler (OnMainWindowDelete);

		// Create VBox to contain menu and game board
//		Hildon.AppView app=this.Appview;
		VBox vbox=new VBox();
		
		// Create MenuBar
		Menu menuFile = new Menu ();

		Menu newGameMenu = new Menu();
		
		menuItemNew = new MenuItem("_New Game");		
		MenuItem menuItemTinyGame = new MenuItem("_Tiny Level");
		menuItemTinyGame.Activated += new EventHandler (menuItemNewTinyGameActivate);
		MenuItem menuItemNormalGame = new MenuItem("_Normal Level");
		menuItemNormalGame.Activated += new EventHandler (menuItemNewGameActivate);
		MenuItem menuItemNewBigGame = new MenuItem("_Big Level");
		menuItemNewBigGame.Activated += new EventHandler (menuItemNewBigGameActivate);

		menuItemStopGame = new MenuItem("_Stop Game");
		menuItemStopGame.Sensitive=false;
		menuItemStopGame.Activated += new EventHandler (menuItemStopGameActivate);
		MenuItem menuItemExit = new MenuItem("_Quit");
		menuItemExit.Activated += new EventHandler (menuItemExitActivate);

		newGameMenu.Append (menuItemTinyGame);
		newGameMenu.Append (menuItemNormalGame);
		newGameMenu.Append (menuItemNewBigGame);
		
		menuItemNew.Submenu = newGameMenu;
		
		MenuItem menuItemAbout = new MenuItem("_About");	
		menuItemAbout.Activated += new EventHandler (menuItemAboutActivate);
	
		menuFile.Append (menuItemNew);
//		menuFile.Append (menuItemTinyGame);
		menuFile.Append (menuItemStopGame);
		menuFile.Append (new SeparatorMenuItem());
		menuFile.Append (menuItemAbout);
		menuFile.Append (new SeparatorMenuItem());
		menuFile.Append (menuItemExit);
	
//		vbox.PackStart(mb,false,false,0);
		this.Menu=menuFile;
		
		// Create Table as Game Board
		tableGame = new Table(6, 6, false);
		for (uint i=0; i<6; i++) {
			for (uint j=0; j<6; j++) {
				button=new ButtonMemory();
				tableGame.Attach(button, i, i+1, j, j+1);
				button.Clicked += new EventHandler (buttonClick);
				buttons[i*6+j]=button;
			}
		}
		board=new VBox();
		board.Add(tableGame);
		vbox.Add(board);

		// Add the toolbar to the main window
		tb = new Toolbar();
		ToolItem toolItem=new ToolItem();
		tbLabel=new Label("Monkey's Memory is now on");
		toolItem.Add(tbLabel);

		// Add the toolbar at the main window
		tb.Insert(toolItem,0);
		this.AddToolbar(tb);

		// Add the vbox to the main window
		this.Add(vbox);

		this.ShowAll ();
		
		// Hide the Game Board
		tableGame.Sensitive=false;

		this.KeyPressEvent += OnKeyPressed;
	}
	
	void OnKeyPressed (object sender, KeyPressEventArgs a)
	{

		// Check if the hardware key "FULLSCREEN" is pressed
		if (a.Event.Key == Gdk.Key.F6) {
			if (isFullScreen) {
				this.Unfullscreen();
			} else {
				this.Fullscreen();
			}
			isFullScreen=!isFullScreen;
		}
	}

	void OnMainWindowDelete (object sender, DeleteEventArgs a)
	{
		Application.Quit ();
		a.RetVal = true;
	}
	
	public void menuItemExitActivate(object o, EventArgs args)
	{
		Application.Quit ();
	}

	public void menuItemNewTinyGameActivate(object o, EventArgs args)
	{
		// Check if the game is already started
		if (tableGame.Sensitive==false) {

			sizeOfBoard=16;

			// Ask the number of playes
			NumberOfPlayers nop=new NumberOfPlayers();
			nop.TransientFor=this;

			// Set the modal style
			nop.Modal=true;
			nop.WindowPosition=Gtk.WindowPosition.CenterOnParent;
		
			nop.Hidden += new EventHandler(numberOfPlayersClose);
			nop.ShowAll();
			nop.Show();
		}
	}

	public void menuItemNewGameActivate(object o, EventArgs args)
	{
		// Check if the game is already started
		if (tableGame.Sensitive==false) {

			sizeOfBoard=36;

			// Ask the number of playes
			NumberOfPlayers nop=new NumberOfPlayers();
			nop.TransientFor=this;

			// Set the modal style
			nop.Modal=true;
			nop.WindowPosition=Gtk.WindowPosition.CenterOnParent;
		
			nop.Hidden += new EventHandler(numberOfPlayersClose);
			nop.ShowAll();
			nop.Show();
		}
	}

	public void menuItemNewBigGameActivate(object o, EventArgs args)
	{
		// Check if the game is already started
		if (tableGame.Sensitive==false) {

			sizeOfBoard=96;

			// Ask the number of playes
			NumberOfPlayers nop=new NumberOfPlayers();
			nop.TransientFor=this;

			// Set the modal style
			nop.Modal=true;
			nop.WindowPosition=Gtk.WindowPosition.CenterOnParent;
		
			nop.Hidden += new EventHandler(numberOfPlayersClose);
			nop.ShowAll();
			nop.Show();
				
		}
	}
	
	public void menuItemStopGameActivate(object o, EventArgs args)
	{
		// Check if the game is already started
		if (tableGame.Visible==true) {

			// Make invisible the Game Board
			tableGame.Sensitive=false;

			// Toggle the state of the item menu
			menuItemNew.Sensitive=true;
    			menuItemStopGame.Sensitive=false;

			// Hide all Images
/*			for (int i=0; i<96; i++) {
				if (buttons[i]!=null) {
					buttons[i].HideImage();
				}
			}
*/			
			tbLabel.Text="Game ended. The Monkey's Memory is now ready for another game.";
		}
	}
	
	private bool GenerateNewGame(int numberOfImage) {
	
		Random rnd=new Random();
		ArrayList imageListTmp=new ArrayList();

		// Read the image list from from disk
		string imageListDirectory = (String)System.Configuration.ConfigurationSettings.AppSettings["image"];
//		string imageListDirectory = "./MemoryIcons";
		imageList=Directory.GetFiles(imageListDirectory,"*.png");
		
		// Test the quantity of image files		
		if (imageList.Length<numberOfImage/2) {
			return false;
		}
		
		ArrayList choice=new ArrayList();

		// Copy the list of Image in a working ArrayList		
		for (int i=0; i<imageList.Length; i++) {
			imageListTmp.Add(imageList[i]);
		}

		// Generate the image choiche
		for (int i=0; i<numberOfImage/2; i+=1) {

			int pos=rnd.Next(imageListTmp.Count);
			String str=(String)imageListTmp[pos];
			choice.Add(str);
			choice.Add(str);
			imageListTmp.RemoveAt(pos);
		}

		// Setup the image to the ButtonMemory
		for (int i=0; i<numberOfImage; i++) {		
			int pos=rnd.Next(choice.Count);
			buttons[i].SetImage((String)choice[pos]);
			choice.RemoveAt(pos);
		}

		return true;
	}

	public void numberOfPlayersClose(object o, EventArgs args) {

		NumberOfPlayers nop=(NumberOfPlayers)o;
		ButtonMemory button=null;
		
		if (nop.ConfirmPlayers) {
		
			nPlayers=nop.PlayersNumber;
			for (int i=0; i<nPlayers; i++) {
				players[i]=new Player();
				players[i].Name=nop.GetPlayer(i);

				if (nop.GetPlayerType(i)!="") {
					players[i].Gamer=(ComputerGamersInterface)nop.CreatePlayer(i);
				}
			}

			// Remove old Game Board
			board.Remove(tableGame);
			
			if (sizeOfBoard==96) {

				// Create Table as Game Board
				tableGame = new Table(12, 8, false);
				for (uint i=0; i<12; i++) {
					for (uint j=0; j<8; j++) {
						button=new ButtonMemory();
						tableGame.Attach(button, i, i+1, j, j+1);
						button.Clicked += new EventHandler (buttonClick);
						buttons[i*8+j]=button;
					}
				}
				GenerateNewGame(96);
				
			} else if (sizeOfBoard==16) {

				// Create Table as Game Board
				tableGame = new Table(4, 4, false);
				for (uint i=0; i<4; i++) {
					for (uint j=0; j<4; j++) {
						button=new ButtonMemory();
						tableGame.Attach(button, i, i+1, j, j+1);
						button.Clicked += new EventHandler (buttonClick);
						buttons[i*4+j]=button;
					}
				}
				GenerateNewGame(16);
			} else {
				// Create Table as Game Board
				tableGame = new Table(6, 6, false);
				for (uint i=0; i<6; i++) {
					for (uint j=0; j<6; j++) {
						button=new ButtonMemory();
						tableGame.Attach(button, i, i+1, j, j+1);
						button.Clicked += new EventHandler (buttonClick);
						buttons[i*6+j]=button;
					}
				}
			}
			if (!GenerateNewGame(sizeOfBoard)) {
				MessageDialog md = new MessageDialog (this, 
                                      				  DialogFlags.DestroyWithParent,
                                   					  MessageType.Error, 
                                      				  ButtonsType.Close, 
                                      				  "Error loading the Images.");

				md.Run ();
				md.Destroy();
				
				tableGame.Sensitive=false;
				
			} else {
				tableGame.ShowAll();
				board.Add(tableGame);
				
				// Make visible the Game Board
				tableGame.Sensitive=true;

				// Toggle the state of the item menu
				menuItemNew.Sensitive=false;
				menuItemStopGame.Sensitive=true;

				buttonsToShow=sizeOfBoard;
				runningPlayer=0;
				showPlayer();
			}
		}
		nop.Destroy();
	}

	public void buttonClick(object o, EventArgs args) {

		ButtonMemory b=(ButtonMemory)o;

		// Test if automatic player
		if (firstButton==null && secondButton==null && players[runningPlayer].Gamer!=null) {
			ButtonInterface b1,b2;
			players[runningPlayer].Gamer.computeNewMovement(sizeOfBoard,
									buttons,
									out b1,
									out b2);
			b1.ShowImage();
			firstButton=(ButtonMemory)b1;
			buttonClick(b2,null);

			return;
		}
		
		// Test if two ButtonMemory is already selected
		if (firstButton!=null && secondButton!=null) {
			firstButton.HideImage();
			firstButton=null;
			secondButton.HideImage();
			secondButton=null;
			runningPlayer = (runningPlayer+1)%nPlayers;
			showPlayer();
			return;
		}

		// Test if the button is already visible
		if (!b.isImgVisible()) {
			b.ShowImage();
			if (firstButton==null) {
				firstButton=b;
			} else {
				if (b.isSameImg(firstButton)) {
					firstButton.Sensitive=false;
					b.Sensitive=false;
					firstButton=null;
					buttonsToShow-=2;
					players[runningPlayer].Score++;
					
					// Test if the game is finished
					if (buttonsToShow<1) {
					
						int i;
						//int maxScoreIndex=0;
						ArrayList maxScoreIndexes=new ArrayList();
						int maxScore=players[0].Score;
						maxScoreIndexes.Add(0);
						for (i=1; i<nPlayers; i++) {
							if (players[i].Score>maxScore) {
								maxScore=players[i].Score;
								maxScoreIndexes.Clear();
								maxScoreIndexes.Add(i);
							} else if (players[i].Score==maxScore) {
								maxScoreIndexes.Add(i);
							}
						}

						showPlayer();
						string msgText;
						msgText = "The game is finish. The winne"+(maxScoreIndexes.Count>1 ? "rs are " : "r is ");
						IEnumerator ien=maxScoreIndexes.GetEnumerator();
						string separatorChar="";
						while (ien.MoveNext()) {
							i=(int)ien.Current;

							msgText += separatorChar + players[i].Name;
							separatorChar=", ";
						}
						msgText += " with "+maxScore+" points.";
						MessageDialog md = new MessageDialog (this, 
		                                      				  DialogFlags.DestroyWithParent,
		                                   					  MessageType.Info, 
		                                      				  ButtonsType.Close, 
		                                      				 msgText);

						md.Run ();
						md.Destroy();
						menuItemStopGameActivate(null,null);
					}
				} else {
					secondButton=b;
				}
			}
		}
		showPlayer();
	}

	private void showPlayer() {
		tbLabel.Text="Player: "+players[runningPlayer].Name+" Score: "+players[runningPlayer].Score;
	}
 	
	public void menuItemAboutActivate(object o, EventArgs args)
	{

		// Display the About Window
		AboutWindow aw=new AboutWindow();
		aw.TransientFor=this;

		// Set the modal style
		aw.Modal=true;
	
		aw.ShowAll();

/*
		Image imgLogo=new Image();
		imgLogo.FromPixbuf = new Gdk.Pixbuf(null,"MonkeysMemory_small.png");
		imgLogo.Xpad=10;
		imgLogo.Ypad=10;
		imgLogo.Name="logo";

		Hildon.Note note=Hildon.Note.NewInformationWithIconName(this,"Monkey's Memory\n\n"+
		                      "This software is developed under the GPL licence by\n"+
		                      "Torello Querci\n"+
		                      "2006 - 2007\n\n"+
		                      "Special Greetings to Everaldo Canuto for the support to the N770-N800 porting.","logo");
		note.Icon = new Gdk.Pixbuf(null,"MonkeysMemory_small.png");
		note.Run();
		note.Destroy();
*/
	}

	public static void Main (string[] args)
	{
	    Osso.Context.Initialize ("monkeysmemory", "0.1.8");

    	    Application.Init ("Monkey's Memory", ref args);

	    // Create the singleton of the PluginsManager
	    new PluginsManager();

            Hildon.Program program = Hildon.Program.Instance;
            program.AddWindow (new MainWindow ());

	    Application.Run ();

            Osso.Context.Deinitialize ();
	}

}
